home *** CD-ROM | disk | FTP | other *** search
/ D.I.S.C. 4 / D.I.S.C. 4.adf / sources / boot_mfm_load.s < prev    next >
Text File  |  1988-01-19  |  12KB  |  416 lines

  1. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  2. ;­            -> DiskBOOTloader <-               ­
  3. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  4. ;­                    1990 by Duke/Level Four                 ­
  5. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  6. ;Notes:    
  7. ;a)    If you want to load and execute CRUNCHED proggys with this 
  8. ;    loader, you should know the address where the decruncher puts
  9. ;    your program into memory to be sure that it won't scratch the
  10. ;    loader-routine. Moreover you have to know that your prog
  11. ;    will crash if you load it into its own decrunch area!
  12. ;    To prevent such crashes, you're able to set the address
  13. ;    of the bootloader and the address where your prog should
  14. ;    be located after loading by changing the address at
  15. ;    "Bootstart". !!!DON'T DECREASE THE OFFSET AT "Buffer"!!!
  16. ;b)    How to install the bootloader on your disk (df0:):
  17. ;    1. assemble this loader (with MASTERSEKA)
  18. ;    2. bstart_boot   <Return>  ;calculate boot-checksum
  19. ;    3. ws0         <Return>  ;(w)rite(s)ector on df(0)
  20. ;    4. BEG>start_boot<Return>
  21. ;    5. SECTOR>0     <Return>  ;start sector 0
  22. ;    6. AMOUNT>2     <Return>  ;write 2 sectors (1024 bytes)
  23. ;    Now you must save the program which you want to load to the
  24. ;    same disk on the correct tracks. You can do that with
  25. ;    MASTERSEKA, too, by typing:
  26. ;    1.ri           <Return>  ;(r)ead (i)mage
  27. ;    2.FILENAME>progname<Return>  ;enter name of your program here
  28. ;    3.BEG>$40000       <Return>  ;load prog. to $40000 for example
  29. ;    4.END>             <Return>  ;load WHOLE prog. just return here
  30. ;    5.wt0           <Return>  ;(w)rite (t)rack on df(0)
  31. ;    6.BEG>$40000       <Return>
  32. ;    7.CYLINDER>enter startcylinder here (1 cylinder=2 tracks)
  33. ;    8.AMOUNT>enter length of your prog in cylinders (1cyl=11264bytes)
  34.  
  35. ;If you have no MASTERSEKA you can use the Amiga Mon or the C-mon
  36. ;to install your program and the loader on disk.
  37. ;Ok. Now your AMIGA should load and execute your program correctly.
  38. ;signed duke/l4
  39.  
  40. ;­­­­­­­­­­­­­­MACRO-definitions­­­­­­­­­­­­­­­­­­
  41. color:    macro
  42.     move.w    #\1,$180(a6)
  43.     endm
  44.  
  45. ;now we waste diskspace by using the following step-macro (but who
  46. ;cares ? - This bootblock is about 920 bytes long...)
  47.  
  48. step:    macro
  49.     move.b    floppystatus(pc),d0
  50.     move.b    d0,d1
  51.     bclr    #0,d0        ;clear DSKSTEP after setting it...STEP!
  52.     move.b    d0,(a0)        ;a0=$bfd100 (CIA-B PRB)
  53.     nop            ;wait a little
  54.     nop
  55.     move.b    d1,(a0)        ;set DSKSTEP back to 1
  56.     bsr.l    timer        ;wait a while
  57.     endm
  58. ;­­­­­­­­­­­­­­­­­Statements­­­­­­­­­­­­­­­­­­­­­­
  59.     Bootstart    =    $20000
  60. ;­bootstart=address of bootloader - may be changed!­
  61.  
  62. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  63.     Buffer        =    Bootstart+$4000
  64. ;­buffer=address of your decoded program - !!!DON'T DECREASE IT!!!­
  65. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  66.  
  67.     Amount        =    22
  68. ;­amount of tracks to read - may be changed, of course!
  69.  
  70.     first_track    =    26
  71. ;­first track to read - may be changed, too!
  72. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  73.  
  74.         org    $40000    ;$40000 should work without 1MB, too.
  75.         load    $40000
  76.  
  77. start_boot:
  78.     dc.b    "DOS",0        ;DOS id 
  79.     dc.l    0        ;space for checksum
  80.     dc.l    $370        ;pointer to rootblock
  81. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  82.     movem.l    d0-d7/a0-a6,-(a7)
  83.     lea    bootstart,a0    ;copy bootblock to bootstart (s. above)
  84.     lea    start_boot(pc),a1
  85.     move.w    #$ff,d7        ;copy 1024 bytes
  86. copy_boot:
  87.     move.l    (a1)+,(a0)+
  88.     dbf    d7,copy_boot
  89.     jmp    bootstart+[start-start_boot] ;jump in loader
  90. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  91. ;Here the loading-routine...
  92.  
  93. S:
  94. Start:
  95.     lea    $dff000,a6    ;coustom base
  96.     lea    s(pc),a5    ;addressoffset (bootblock MUST be pc-
  97.                 ;relative)
  98.  
  99.     move.w    $01c(a6),oldint-s(a5)
  100.     ori.w    #$8000,oldint-s(a5)
  101.     move.w    $002(a6),olddma-s(a5)
  102.     ori.w    #$8000,olddma-s(a5)
  103.     move.w    $010(a6),oldadk-s(a5)
  104.     ori.w    #$8000,oldadk-s(a5)
  105.     move.w    #$7fff,d0
  106.     move.w    d0,$096(a6)    ;switch dma's off
  107.     move.w    d0,$09a(a6)    ;forbid interrupts
  108.     move.w    d0,$09c(a6)    ;clear intreq
  109.     move.w    d0,$09e(a6)    ;clear adkcon
  110.  
  111.     color    0        ;background color while loading
  112.     move.w    #$8210,$96(a6)    ;diskdma on!
  113.  
  114. ;select DRIVE:      3210
  115.     moveq    #%0001,d0    ;set right bit for drive 0,1,2 or 3
  116.     bsr.l    select_drive    ;select drive from which you want to read
  117.  
  118.     bsr.l    motor_on    ;drivemotor on
  119.  
  120.     moveq    #0,d0        ;move track number ->d0
  121.     bsr.l    head_pos    ;move head to track 0 (orientation)
  122.  
  123.     bsr.l    init_read    ;init diskregisters
  124. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  125.     move.w    #Amount,trackct-s(a5);set trackcounter
  126. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  127.  
  128. Load_tracks:
  129.     bchg    #1,$bfe001    ;switch led on/off each cylinder
  130.     move.w    track(pc),d0    ;move head to starttrack
  131.     bsr.l    head_pos
  132.     bsr.l    test_disk    ;check if disk in drive
  133. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  134.     bsr.l    read_track    ;read track
  135.     bsr.l    decode_track    ;decode track
  136. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  137.     addq.w    #1,track-s(a5)    ;next track (add/sub=increase/decrease)
  138.     subq.w    #1,trackct-s(a5);decrease trackcounter
  139.     bne.s    load_tracks
  140. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  141.     bsr.l    Motor_off    ;drivemotor off
  142.     move.l    bufferpt2(pc),a0;change jump in-address at bufferpt2
  143.     jsr    (a0)        ;jump in loaded program
  144. Exit:
  145.     move.w    Olddma(pc),$096(a6)
  146.     move.w    Oldint(pc),$09a(a6)
  147.     move.w    Oldadk(pc),$09e(a6)
  148.     movem.l    (a7)+,d0-d7/a0-a6
  149.  
  150. ;Here the normal bootroutine is following. But please notice that it's
  151. ;now impossible for the operating-system to access its disk operations
  152. ;correctly, because we used the hardware in that direct way without
  153. ;permission of the operating-system. That's the reason why you'll see
  154. ;a 'not a DOS disk'-requester after returning from the loader. So you
  155. ;see that it would be better to jump into the reset-routine instead 
  156. ;of accessing the following 'find resident'-routine. 
  157.  
  158. ;Reset your AMIGA...
  159. ;    move.l    $4.w,a6
  160. ;    clr.l    38(a6)        ;destroy chkbase to force...
  161. ;    move.l    #$fc00d2,$80.w
  162. ;    trap    #0        ;...cold reset
  163.  
  164. ;...or be stupid and try the normal boot-procedure.
  165.     move.l    $4.w,a6
  166.     lea     Dosname(pc),a1
  167.     jsr     -96(a6)        ;FindResident()
  168.     move.l     d0,a0
  169.     move.l     22(a0),a0
  170.     moveq    #0,d0
  171.     Rts
  172.  
  173. dosname:dc.b    "dos.library",0
  174. olddma:    dc.w    0
  175. oldint:    dc.w    0
  176. oldadk:    dc.w    0
  177. track:    dc.w    first_track
  178. trackct:dc.w    0        ;trackcounter
  179.  
  180. Init_Read:
  181.     clr.w    $24(a6)        ;DSKLEN->forbid diskdma and writing
  182.     move.w    #$4489,$7e(a6)    ;set standard SYNC
  183.     move.w    #$7f00,$9e(a6)    ;clear ADKCON
  184.     move.w    #$9500,$9e(a6)    ;set required bits
  185.     move.w    #$0002,$9c(a6)    ;clear DSKBLK bit
  186.     Rts
  187.  
  188. Read_Track:
  189.     clr.w    $24(a6)        ;DSKLEN->forbid diskdma
  190.     lea    trackbuff(pc),a0
  191.     move.l    a0,$20(a6)    ;set DSKPTH and DSKPTL
  192.     move.w    #$9a00,$24(a6)    ;enable diskdma and set amount of
  193.     move.w    #$9a00,$24(a6)    ;words+2 to transfer.
  194.  
  195. Wait_Dma:
  196.     btst    #1,$1f(a6)    ;DSKBLK=0 ?
  197.     beq.s   Wait_Dma    ;yeah=> wait
  198.     clr.w    $24(a6)        ;forbid writing
  199.     move.w  #$0002,$9c(a6)    ;clear DSKBLK
  200.     Rts
  201.  
  202. ;­Timer A-delay
  203. timer:                ;waits ca. 1/100 sec.
  204.     move.b    #$00,$bfde00    ;clear CRA
  205.     move.b    #$7f,$bfdd00    ;clear ICR
  206.     move.b    #$00,$bfd400    ;timer a -low
  207.     move.b    #$20,$bfd500    ;timer a -high (wait-value=$2000)
  208.     move.b    #$09,$bfde00    ;set oneshot/start
  209. wait_timer:
  210.     btst    #0,$bfdd00    ;test ta-bit/that clears ICR
  211.     beq.s    wait_timer
  212.     rts
  213.  
  214. Wait_ready:
  215.     btst    #5,$bfe001    ;wait for DRIVEREADY
  216.     bne.s    Wait_ready    ;it's useless here, because the wait-
  217.     Rts            ;loop is long enough, but......
  218.  
  219. test_disk:
  220.     btst    #2,$bfe001
  221.     beq.s    error
  222.     Rts
  223. error:    move.w    $dff006,$dff180
  224.     bra.s    error
  225.  
  226. Select_Drive:
  227.     lea    floppystatus(pc),a0
  228.     lea    motorstatus(pc),a1
  229.     moveq    #-1,d1        ;$ffffffff -> d1
  230.     lsl.w    #3,d0        ;shift selectbit to right position
  231.     eor.b    d0,d1        ;selectbit must be zero
  232.     move.b    d1,(a0)        ;save byte ->floppystatus.b
  233.     eori.b    #$80,d1        ;clear DSKMOTOR-bit
  234.     move.b    d1,(a1)        ;save byte ->motorstatus.b
  235.     Rts
  236.  
  237. Motor_On:
  238.     move.b    #$7f,$bfd100    ;Bits 0-6 HIGH/Bit 7 LOW
  239.     nop
  240.     nop
  241.     move.b    motorstatus(pc),d0
  242.     move.b    d0,$bfd100    ;DSKMOTOR and DSKSELx LOW
  243.     bsr.l    Wait_Ready
  244.     Rts
  245.  
  246. Motor_Off:
  247.     move.b    #$ff,$bfd100    ;Bits 0-7 HIGH
  248.     nop
  249.     nop
  250.     move.b    motorstatus(pc),d0
  251.     ori.b    #$80,d0        ;DSKMOTOR HIGH DSKSELx LOW
  252.     move.b    d0,$bfd100
  253.     Rts
  254.  
  255. ;This routine moves the r/w-head to a track with the number stored
  256. ;in d0. A similar routine is also used by the operating-system
  257. ;(at $fea3da)
  258.  
  259. Head_Pos:
  260.     lea    $bfd100,a0
  261.     lea    s(pc),a5
  262.     tst.w    d0            ;track number=0?
  263.     beq.l    Move_zero        ;yeah=>step to track 0
  264.     move.w    Tracknum(pc),d2        ;current track number
  265.     cmp.w    d2,d0            ;oldtrack=newtrack ?
  266.     beq.s    Head_end        ;yes=>don't move head
  267.     move.w    d0,d3
  268.     move.b    Floppystatus(pc),d1
  269.     bset    #2,d1            ;select head 0 (lower side)
  270.     btst    #0,d3            ;track number even ?
  271.     beq.s    Down_Right        ;yes=>head 0 is the right one
  272.     bclr    #2,d1            ;no, select head 1 (upper side)
  273. Down_Right:
  274.     move.b    d1,Floppystatus-s(a5)
  275.     move.b    d1,(a0)
  276.     move.w    d3,Tracknum-s(a5)    ;save new track-number
  277.     lsr.w    #1,d2            ;d2=current cylinder
  278.     lsr.w    #1,d3            ;d3=new cylinder
  279.     sub.w    d3,d2            ;make difference
  280.     bmi.s    Seek_in            ;diff. negativ=> step in
  281.     beq.s    Head_end
  282.     bra.s    Seek_out        ;diff. positiv=> step out
  283. Seek_in:
  284.     bclr    #1,d1            ;step in
  285.     move.b    d1,Floppystatus-s(a5)
  286.     neg.w    d2            ;make number positive
  287.     bra.s    Step_Ok
  288. Seek_out:
  289.     bset    #1,d1            ;step out
  290.     move.b    d1,Floppystatus-s(a5)
  291.     bra.s    Step_Ok
  292. HeadStep:
  293.     Step                ;call step-macro
  294. Step_Ok:
  295.     dbf    d2,HeadStep
  296. Head_end:
  297.     Rts    
  298.  
  299. Move_zero:                ;move head to track zero
  300.     move.b    Floppystatus(pc),d1
  301.     bset    #2,d1
  302.     bset    #1,d1
  303.     move.b    d1,Floppystatus-s(a5)
  304.     clr.w    Tracknum-s(a5)
  305. Headzero:
  306.     btst    #4,$bfe001        ;test if zero
  307.     beq.s    zero1
  308.     Step
  309.     bra.s    Headzero
  310. zero1:
  311.     bclr    #1,Floppystatus-s(a5)
  312.     Step
  313.     bset    #1,Floppystatus-s(a5)
  314.     Step
  315.     bra.s    Head_end
  316.  
  317. ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
  318. ;This routine decodes the block-header and checks the format-sign.
  319. ;After this it calculates the checksum from the data-block and
  320. ;compares it with the checksum wich is stored in the block-header.
  321. ;While calculating the checksum it decodes the data block, of course.
  322.  
  323. decode_track:
  324.     move.l    bufferpt(pc),a0        ;pointer to decodebuffer
  325.     lea    trackbuff(pc),a1    ;pointer to MFMbuffer
  326.     moveq    #11-1,d5        ;decode 11 blocks (-1 coz dbf)
  327.     move.l    #$55555555,d3        ;filter for tactbits
  328.  
  329. decode_all_blocks:
  330.     cmpi.w    #$4489,(a1)+        ;1st sync-word found ?
  331.     bne.s    decode_all_blocks    ;no=> go on searching
  332.  
  333. sync_found:
  334.     cmpi.w    #$4489,(a1)        ;2. sync-word found ?
  335.     bne.s    syncs_ok        ;no=> all syncs skipped
  336.     addq.w    #2,a1            ;yes=>
  337.     bra.s    sync_found        ;search for remaining syncs
  338.  
  339. syncs_ok:                ;decode infoblock
  340.     move.l    (a1)+,d0        ;odd bits
  341.     move.l    (a1)+,d1        ;even bits
  342.     and.l    d3,d0
  343.     and.l    d3,d1
  344.     add.l    d0,d0
  345.     or.l    d1,d0
  346.  
  347.     swap    d0
  348.     andi.w    #$ff00,d0        ;mask format-sign (must be $ff)
  349.     cmpi.w    #$ff00,d0        ;right value?
  350.     bne.s    formatrerror        ;no==>ERROR!
  351.     swap    d0
  352.  
  353.     andi.w    #$ff00,d0        ;mask sector number*256
  354.     add.w    d0,d0            ;d0=d0*2 (=sector number*512)
  355.     move.l    a0,a2            ;address of decodebuffer ->a2
  356.     adda.w    d0,a2            ;calc. correct destination
  357.  
  358.     adda.w    #40,a1            ;address of checksum ->a1
  359.     move.l    (a1)+,d4        ;decode checksum
  360.     move.l    (a1)+,d1
  361.     and.l    d3,d4
  362.     and.l    d3,d1
  363.     add.l    d4,d4
  364.     or.l    d1,d4            ;store checksum ->d4
  365.  
  366.     moveq    #128-1,d6        ;decode 128*2 longs to 512 bytes 
  367.     moveq    #0,d2            ;clear datachecksum
  368.  
  369. decodeblock:                ;decode datablock
  370.     move.l    512(a1),d1        ;even bits
  371.     move.l    (a1)+,d0        ;odd bits
  372.  
  373.     eor.l    d0,d2            ;calc checksum
  374.     eor.l    d1,d2            ;dito
  375.  
  376.     and.l    d3,d0            ;decode longword
  377.     and.l    d3,d1
  378.     add.l    d0,d0
  379.     or.l    d1,d0
  380.     move.l    d0,(a2)+        ;store longword in buffer
  381.     dbf    d6,decodeblock        ;decode next longword
  382.  
  383.     and.l    d3,d2            ;remove tactbits
  384.     cmp.l    d4,d2            ;checksum correct ?
  385.     bne.s    chksumerror        ;no=>ERROR!
  386.     adda.w    #512,a1            ;reach next block
  387.     dbf    d5,decode_all_blocks
  388.  
  389.     adda.w    #$1600,a0        ;bufferadr.+ 1track (5632bytes)
  390.     move.l    a0,bufferpt-s(a5)    ;store new address
  391.     Rts
  392.  
  393. chksumerror:
  394.     color        $f00        ;backgroundcolor red
  395.     st        chkflag-s(a5)    ;set errorflag to -1
  396.     Rts
  397.  
  398. formatrerror:
  399.     color        $f00        ;backgroundcolor red
  400.     st        hdrflag-s(a5)    ;set errorflag to -1
  401.     Rts
  402.  
  403. tracknum:    dc.w    0
  404. floppystatus:    dc.b    0
  405. motorstatus:    dc.b    0
  406. chkflag:    dc.b    0
  407. hdrflag:    dc.b    0
  408. bufferpt:    dc.l    buffer
  409. bufferpt2:    dc.l    buffer        ;here you can change the jump-
  410.                     ;in address of your prog.
  411.         dc.b    "­ Loader by Duke of LEVEL FOUR - ASD ­"
  412. Even
  413. trackbuff:
  414. endprg:
  415.         blk.b    200,0 ;just to clear remaining bytes in mem
  416.